package com.orange.common.utils;

import java.util.concurrent.ThreadLocalRandom;

/**
 * TODO
 *
 * @Author YWF
 * @Date 2025/8/15 17:13
 */
public class IdsUtils {

    // 常量定义
    private static final String BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final int MAX_BITS = 26; // 36^5 = 60,466,176 需要26位
    private static final int MAX_VALUE = (1 << MAX_BITS) - 1;
    private static final int XOR_KEY = 0x35D2BE8;

    // 预计算编码表（核心优化点）
    private static final char[] BASE36_CHARS = BASE36.toCharArray();
    private static final int[] BASE36_INDEX = new int[128]; // ASCII码范围

    static {
        // 初始化字符索引表（提速解码）
        for (int i = 0; i < BASE36.length(); i++) {
            char c = BASE36.charAt(i);
            BASE36_INDEX[c] = i;
        }
    }

    // 加密：使用预计算编码表
    public static String encode(int serial) {
        if (serial < 0 || serial >= (1 << MAX_BITS)) {
            throw new IllegalArgumentException("输入值需在0-" + (MAX_VALUE) + "之间");
        }

        int obfuscated = serial ^ XOR_KEY;
        char[] code = new char[5];
        for (int i = 4; i >= 0; i--) {
            code[i] = BASE36_CHARS[obfuscated % 36]; // 直接查表
            obfuscated /= 36;
        }
        return new String(code);
    }

    // 解密：使用预计算索引表
    public static int decode(String code) {
        if (code.length() != 5) throw new IllegalArgumentException();

        int value = 0;
        for (int i = 0; i < 5; i++) {
            char c = code.charAt(i);
            // 安全检查+查表
            if (c >= BASE36_INDEX.length || BASE36_INDEX[c] == 0 && c != '0') {
                throw new IllegalArgumentException("非法字符: " + c);
            }
            value = value * 36 + BASE36_INDEX[c];
        }
        return value ^ XOR_KEY;
    }

    // 验证测试
    public static void main(String[] args) {
        test(0);
        test(12345);
        test(999999);
        test(MAX_VALUE); // 最大值测试
        ThreadLocalRandom random = ThreadLocalRandom.current();
        for (int i = 1000; i < 1050; i++) {
            //test(random.nextInt(MAX_VALUE + 1));
            test(i);
        }
    }

    private static void test(int num) {
        String encoded = encode(num);
        int decoded = decode(encoded);
        System.out.printf("输入:%-8d 加密:%-6s 还原:%-8d %s%n",
                num, encoded, decoded, (num == decoded ? "✓" : "✗"));
    }

}
